package com.yfqy.admin.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.yfqy.admin.conf.Idgenerator.SnowflakeIdGenerator;
import com.yfqy.admin.constant.MyConstants;
import com.yfqy.admin.domain.dto.brand.AddBrand;
import com.yfqy.admin.domain.dto.brand.BrandDetail;
import com.yfqy.admin.domain.dto.brand.BrandQuery;
import com.yfqy.admin.domain.dto.brand.ModifyBrand;
import com.yfqy.admin.domain.entity.Brand;
import com.yfqy.admin.domain.entity.SysUser;
import com.yfqy.admin.enums.ResponseEnum;
import com.yfqy.admin.domain.mapper.BrandMapper;
import com.yfqy.admin.domain.mapper.SysUserMapper;
import com.yfqy.admin.security.login.LoginUserInfo;
import com.yfqy.admin.service.BrandService;
import com.yfqy.admin.util.AuthUserContext;
import com.yfqy.admin.domain.vo.common.ResultVO;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
public class BrandServiceImpl implements BrandService {

    private final BrandMapper brandMapper;
    private final SysUserMapper sysUserMapper;
    private final SnowflakeIdGenerator idGenerator;

    public BrandServiceImpl(BrandMapper brandMapper, SysUserMapper sysUserMapper, SnowflakeIdGenerator idGenerator) {
        this.brandMapper = brandMapper;
        this.sysUserMapper = sysUserMapper;
        this.idGenerator = idGenerator;
    }

    @Override
    public int deleteByPrimaryKey(Long id) {
        return brandMapper.deleteByPrimaryKey(id);
    }

    @Override
    public int insert(Brand record) {
        return brandMapper.insert(record);
    }

    @Override
    public int insertSelective(Brand record) {
        return brandMapper.insertSelective(record);
    }

    @Override
    public Brand selectByPrimaryKey(Long id) {
        return brandMapper.selectByPrimaryKey(id);
    }

    @Override
    public int updateByPrimaryKeySelective(Brand record) {
        return brandMapper.updateByPrimaryKeySelective(record);
    }

    @Override
    public int updateByPrimaryKey(Brand record) {
        return brandMapper.updateByPrimaryKey(record);
    }

    @Override
    public ResultVO<PageInfo<BrandDetail>> brandPageList(BrandQuery brandQuery) {
        PageHelper.startPage(brandQuery.getPageIndex(), brandQuery.getPageSize());
        List<BrandDetail> brands = brandMapper.selectListByNameAndIsShow(brandQuery.getName(), brandQuery.getShow());
        PageInfo<BrandDetail> pageInfo = new PageInfo<>(brands);
        PageHelper.clearPage();
        return ResultVO.data(pageInfo);
    }

    @Override
    public ResultVO<Long> addBrand(AddBrand addBrand) {
        Brand brand = brandMapper.selectOneByName(addBrand.getName());
        if (Objects.isNull(brand)) {
            Brand bean = BeanUtil.toBean(addBrand, Brand.class);
            LoginUserInfo loginUserInfo = AuthUserContext.getLocalAuthUser();
            if (Objects.nonNull(loginUserInfo)) {
                bean.setCreatedBy(loginUserInfo.getId());
                bean.setModifiedBy(loginUserInfo.getId());
            }
            bean.setId(idGenerator.nextId());
            brandMapper.insertSelective(bean);
            return ResultVO.data(bean.getId());
        }
        return ResultVO.fail(ResponseEnum.BRAND_IS_EXIT);
    }

    @Override
    public ResultVO<Void> modifyBrand(ModifyBrand modifyBrand) {
        Brand brandById = brandMapper.selectByPrimaryKey(modifyBrand.getId());
        if (Objects.isNull(brandById)) {
            return ResultVO.fail(ResponseEnum.BRAND_IS_INVALID);
        }
        Brand brandByName = brandMapper.selectOneByName(modifyBrand.getName());
        if (Objects.nonNull(brandByName) && !brandByName.getId().equals(brandById.getId())) {
            return ResultVO.fail(ResponseEnum.BRAND_IS_EXIT);
        }
        BeanUtil.copyProperties(modifyBrand, brandById, CopyOptions.create().setIgnoreNullValue(true));
        LoginUserInfo loginUserInfo = AuthUserContext.getLocalAuthUser();
        Long modifiedBy = Objects.nonNull(loginUserInfo) ? loginUserInfo.getId() : MyConstants._L1;
        brandById.setModifiedBy(modifiedBy);
        brandMapper.updateByPrimaryKeySelective(brandById);
        return ResultVO.success();
    }

    @Override
    public ResultVO<BrandDetail> selectById(Long brandId) {
        Brand brand = brandMapper.selectByPrimaryKey(brandId);
        if (Objects.isNull(brand)) {
            return ResultVO.fail(ResponseEnum.BRAND_IS_INVALID);
        }
        BrandDetail brandDetail = BeanUtil.toBean(brand, BrandDetail.class);
        List<Long> userIds = Stream.of(brand.getCreatedBy(), brand.getModifiedBy()).filter(id -> !MyConstants._L1.equals(id)).toList();
        if (CollUtil.isNotEmpty(userIds)) {
            Map<Long, SysUser> sysUserMap = sysUserMapper.selectByIds(userIds).stream().collect(Collectors.toMap(SysUser::getId, Function.identity()));
            brandDetail.setCreatedByName(Optional.ofNullable(sysUserMap.get(brandDetail.getCreatedBy())).map(u -> String.format("%s(%s)", u.getNickname(), u.getUsername())).orElse("-"));
            brandDetail.setModifiedByName(Optional.ofNullable(sysUserMap.get(brandDetail.getModifiedBy())).map(u -> String.format("%s(%s)", u.getNickname(), u.getUsername())).orElse("-"));
        }
        return ResultVO.data(brandDetail);
    }


}
